

#include "HeaderFiles.h"


/*!
    \brief      pwm gpio initialize configure
    \param[in]  none
    \param[out] none
    \retval     none
*/
void pwm_gpio_init(void)
{
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_GPIOB);
	rcu_periph_clock_enable(RCU_GPIOE);
	rcu_periph_clock_enable(RCU_GPIOC);
	
    rcu_periph_clock_enable(RCU_AF);
	
	// motor #1 PWM gpio configure(Timer0)
	
	/*enable TIMER0 full remapping*/
	gpio_pin_remap_config(GPIO_TIMER0_FULL_REMAP, ENABLE);
	gpio_pin_remap_config(GPIO_TIMER0_FULL_REMAP, ENABLE);
	gpio_pin_remap_config(GPIO_TIMER0_FULL_REMAP, ENABLE);
	
    /*configure PE9/11/13/14(TIMER0 CH0/CH1/CH2/CH3) as alternate function*/
    gpio_init(GPIOE,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_9);
	gpio_init(GPIOE,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_11);
	
	#if 1
    gpio_init(GPIOE,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_13);
	#else
	gpio_init(GPIOE,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_13);
	gpio_bit_set(GPIOE, GPIO_PIN_13);
	#endif
	
	gpio_init(GPIOE,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_14);

    /*configure PE8/10/12*/
	#if 0
    gpio_init(GPIOE,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_8);
    gpio_init(GPIOE,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_10);
	#else
	gpio_init(GPIOE,GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,GPIO_PIN_8);	
	gpio_init(GPIOE,GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,GPIO_PIN_10);	
	#endif
	
	#if 0
    gpio_init(GPIOE,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_12);
	
	#else
	gpio_init(GPIOE,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_12);
	gpio_bit_reset(GPIOE, GPIO_PIN_12);
	#endif

	
	/*configure PE15(TIMER0 BKIN) as alternate function*/
    gpio_init(GPIOE,GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,GPIO_PIN_15);
	
	
	// motor #2 PWM gpio configure(Timer7)
		
    /*configure PC6/7/8(TIMER7 CH0/CH1/CH2) as alternate function*/
    gpio_init(GPIOC,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_6);
	gpio_init(GPIOC,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_7);
    gpio_init(GPIOC,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_8);	
    gpio_init(GPIOC,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_9);	
	
	
	#if 0
    gpio_init(GPIOB,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_0);
    gpio_init(GPIOB,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_1);
	#else
	
	gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_0);
	gpio_bit_reset(GPIOB, GPIO_PIN_0);
	
    gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_1);
	gpio_bit_reset(GPIOB, GPIO_PIN_1);
	
	#endif	
	
	// PWM gpio configure (Timer2)
	#if 1
	/*configure PA6/7 PB0/1(TIMER2 CH0/CH1/CH2/CH3) as alternate function*/
    gpio_init(GPIOA,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_6);
	gpio_init(GPIOA,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_7);
	#else
    gpio_init(GPIOA,GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,GPIO_PIN_6);
	gpio_init(GPIOA,GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,GPIO_PIN_7);
	#endif	
	
}


/*!
    \brief      pwm resgiter initialize configure
    \param[in]  none
    \param[out] none
    \retval     none
*/
void pwm_resgiter_init(void)
{
	timer_oc_parameter_struct timer_ocintpara;
    timer_parameter_struct timer_initpara;
    timer_break_parameter_struct timer_breakpara;
	
	uint16_t i = 0;
	uint32_t Timerx_num[2] = {TIMER0, TIMER7};

    rcu_periph_clock_enable(RCU_TIMER0);
    rcu_periph_clock_enable(RCU_TIMER7);

    timer_deinit(TIMER0);
    timer_deinit(TIMER7);
	
	for(i=0;i<2;i++)
	{				
		/* TIMER0/7 configuration */
		timer_initpara.prescaler         = 0;
		timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
		timer_initpara.counterdirection  = TIMER_COUNTER_UP;
		timer_initpara.period            = PWM_PERIOD_REG-1;
		timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
		timer_initpara.repetitioncounter = 0;
		timer_init(Timerx_num[i],&timer_initpara);

		/* CH0/CH0N configuration in PWM mode0 */
		timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
		timer_ocintpara.outputnstate = TIMER_CCXN_ENABLE;
		timer_ocintpara.ocpolarity   = TIMER_OC_POLARITY_LOW;
		timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
		timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
		timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_HIGH;

		timer_channel_output_config(Timerx_num[i],TIMER_CH_0,&timer_ocintpara);
		timer_channel_output_config(Timerx_num[i],TIMER_CH_1,&timer_ocintpara);
		timer_channel_output_config(Timerx_num[i],TIMER_CH_2,&timer_ocintpara);
		timer_channel_output_config(Timerx_num[i],TIMER_CH_3,&timer_ocintpara);
			
		timer_channel_output_pulse_value_config(Timerx_num[i],TIMER_CH_0,0);
		timer_channel_output_mode_config(Timerx_num[i],TIMER_CH_0,TIMER_OC_MODE_PWM1);
		timer_channel_output_shadow_config(Timerx_num[i],TIMER_CH_0,TIMER_OC_SHADOW_ENABLE);
			
		timer_channel_output_pulse_value_config(Timerx_num[i],TIMER_CH_1,0);
		timer_channel_output_mode_config(Timerx_num[i],TIMER_CH_1,TIMER_OC_MODE_PWM1);
		timer_channel_output_shadow_config(Timerx_num[i],TIMER_CH_1,TIMER_OC_SHADOW_ENABLE);
			
		timer_channel_output_pulse_value_config(Timerx_num[i],TIMER_CH_2,PWM_PERIOD_REG);
		timer_channel_output_mode_config(Timerx_num[i],TIMER_CH_2,TIMER_OC_MODE_PWM1);
		timer_channel_output_shadow_config(Timerx_num[i],TIMER_CH_2,TIMER_OC_SHADOW_ENABLE);
			
		timer_channel_output_pulse_value_config(Timerx_num[i],TIMER_CH_3,0);
		timer_channel_output_mode_config(Timerx_num[i],TIMER_CH_3,TIMER_OC_MODE_PWM1);
		timer_channel_output_shadow_config(Timerx_num[i],TIMER_CH_3,TIMER_OC_SHADOW_ENABLE);   
		
//		timer_master_slave_mode_config(Timerx_num[i],TIMER_MASTER_SLAVE_MODE_ENABLE);
//		timer_update_source_config(Timerx_num[i], TIMER_UPDATE_SRC_REGULAR);
//		timer_update_event_enable(Timerx_num[i]);		
		timer_master_output_trigger_source_select(Timerx_num[i], TIMER_TRI_OUT_SRC_UPDATE);   
			
		/* automatic output enable, break, dead time and lock configuration*/
		timer_breakpara.runoffstate      = TIMER_ROS_STATE_DISABLE;
		timer_breakpara.ideloffstate     = TIMER_IOS_STATE_DISABLE ;
		timer_breakpara.deadtime         = 0;
		timer_breakpara.breakpolarity    = TIMER_BREAK_POLARITY_LOW;
		timer_breakpara.outputautostate  = TIMER_OUTAUTO_ENABLE;
		timer_breakpara.protectmode      = TIMER_CCHP_PROT_0;
		timer_breakpara.breakstate       = TIMER_BREAK_DISABLE;
		timer_break_config(Timerx_num[i],&timer_breakpara);

		/* TIMER0/7 primary output function enable */
		timer_primary_output_config(Timerx_num[i],ENABLE);

		/* auto-reload preload enable */
		timer_auto_reload_shadow_enable(Timerx_num[i]);

		#if 0
		/* TIMER0 counter enable */
		timer_enable(Timerx_num[i]);	
		#endif
	}
	
    timer_channel_output_pulse_value_config(Timerx_num[0],TIMER_CH_2,PWM_PERIOD_REG);

	timer_channel_output_pulse_value_config(Timerx_num[1],TIMER_CH_2,PWM_PERIOD_REG);	
	timer_channel_output_pulse_value_config(Timerx_num[1],TIMER_CH_3,PWM_PERIOD_REG);
	
	
	
	
	
	#if 1
	timer_enable(Timerx_num[0]);	
	timer_enable(Timerx_num[1]);	
	#endif
}



/*!
    \brief      
    \param[in]  none
    \param[out] none
    \retval     none
*/

void pwm_timer2_init(void)
{
	timer_oc_parameter_struct timer_ocintpara;
    timer_parameter_struct timer_initpara;
    timer_break_parameter_struct timer_breakpara;

    rcu_periph_clock_enable(RCU_TIMER2);
	
    timer_deinit(TIMER2);
	
	/* TIMER2 configuration */
	timer_initpara.prescaler         = 1;
	timer_initpara.alignedmode       = TIMER_COUNTER_CENTER_BOTH;
	timer_initpara.counterdirection  = TIMER_COUNTER_UP;
	timer_initpara.period            = PWM_PERIOD_REG-1;
	timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
	timer_initpara.repetitioncounter = 0;
	timer_init(TIMER2,&timer_initpara);

	/* CH0 configuration in PWM mode0 */
	timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
	timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
	timer_ocintpara.ocpolarity   = TIMER_OC_POLARITY_HIGH;
	timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
	timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
	timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;

	timer_channel_output_config(TIMER2,TIMER_CH_0,&timer_ocintpara);
	timer_channel_output_config(TIMER2,TIMER_CH_1,&timer_ocintpara);
	timer_channel_output_config(TIMER2,TIMER_CH_2,&timer_ocintpara);
	timer_channel_output_config(TIMER2,TIMER_CH_3,&timer_ocintpara);
				
	timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_0,PWM_PERIOD_REG);
	timer_channel_output_mode_config(TIMER2,TIMER_CH_0,TIMER_OC_MODE_PWM1);
	timer_channel_output_shadow_config(TIMER2,TIMER_CH_0,TIMER_OC_SHADOW_ENABLE);
		
	timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_1,PWM_PERIOD_REG);
	timer_channel_output_mode_config(TIMER2,TIMER_CH_1,TIMER_OC_MODE_PWM1);
	timer_channel_output_shadow_config(TIMER2,TIMER_CH_1,TIMER_OC_SHADOW_ENABLE);
		
	timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_2,PWM_PERIOD_REG);
	timer_channel_output_mode_config(TIMER2,TIMER_CH_2,TIMER_OC_MODE_PWM1);
	timer_channel_output_shadow_config(TIMER2,TIMER_CH_2,TIMER_OC_SHADOW_ENABLE);
		
	timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_3,PWM_PERIOD_REG);
	timer_channel_output_mode_config(TIMER2,TIMER_CH_3,TIMER_OC_MODE_PWM1);
	timer_channel_output_shadow_config(TIMER2,TIMER_CH_3,TIMER_OC_SHADOW_ENABLE);
		
	/* automatic output enable, break, dead time and lock configuration*/
	timer_breakpara.runoffstate      = TIMER_ROS_STATE_DISABLE;
	timer_breakpara.ideloffstate     = TIMER_IOS_STATE_DISABLE;
	timer_breakpara.deadtime         = 6;
	timer_breakpara.breakpolarity    = TIMER_BREAK_POLARITY_LOW;
	timer_breakpara.outputautostate  = TIMER_OUTAUTO_DISABLE;
	timer_breakpara.protectmode      = TIMER_CCHP_PROT_0;
	timer_breakpara.breakstate       = TIMER_BREAK_DISABLE;
	timer_break_config(TIMER2,&timer_breakpara);

	/* auto-reload preload enable */
	timer_auto_reload_shadow_enable(TIMER2);

	#if 1
	/* TIMER2 counter enable */
	timer_enable(TIMER2);	
	#endif

}


/*!
    \brief      
    \param[in]  none
    \param[out] none
    \retval     none
*/

void pwm_init(void)
{
	pwm_gpio_init();

	pwm_resgiter_init();
	
	pwm_timer2_init();
}


/*!
    \brief      
    \param[in]  none
    \param[out] none
    \retval     none
*/

void pwm_output(uint16_t *duty_addr, uint16_t num)
{
	uint32_t Timerx_num[2] = {TIMER0, TIMER7};

	uint32_t duty_A = *duty_addr;
	uint32_t duty_B = *(duty_addr + 1);
	uint32_t duty_C = *(duty_addr + 2);
	
	timer_channel_output_pulse_value_config(Timerx_num[num], TIMER_CH_0, duty_A);
	timer_channel_output_pulse_value_config(Timerx_num[num], TIMER_CH_1, duty_B);
	timer_channel_output_pulse_value_config(Timerx_num[num], TIMER_CH_2, duty_C);

}



/*!
    \brief      
    \param[in]  none
    \param[out] none
    \retval     none
*/

void single_pwm_output(int16_t duty, uint16_t num)
{

	
	




}


